﻿/****************************************************
     * 作    者：Leng
     * 邮    箱：2947672@qq.com
     * 文件名称：AssetsHelper
     * 创建时间：2021/7/12 星期一 21:54:38
     * 功    能：
*****************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using libx;

namespace ET
{
    public enum AssetsType
    {
        Prefab,
        TextAsset,
        Texture,
        Sprite,
        Config,
        UI,
        FUI,
        FUISprite
    }

    public static class AssetsHelper
    {
        /// <summary>
        /// 同步加载资源
        /// </summary>
        /// <param name="path">文件名(带热更资源下目录、带后辍)</param>
        /// <param name="type">类型</param>
        /// <param name="create">是否创建实例</param>
        /// <returns></returns>
        public static T LoadAssets<T>(string assetPath, AssetsType type, bool isCreate = false) where T : UnityEngine.Object
        {
            AssetRequest result = null;
            string path = GetPath(assetPath, type);
            result = libx.Assets.LoadAsset(path, typeof(T));
            if(isCreate)
            {
                GameObject go = UnityEngine.Object.Instantiate(result.asset) as GameObject;
                return go as T;
            }
            return result.asset as T;

        }

        /// <summary>
        /// 异步加载资源
        /// </summary>
        /// <param name="path">文件名(带热更资源下目录、带后辍)</param>
        /// <param name="assetType">类型</param>
        /// <param name="create">异步加载完成后是否创建实例</param>
        /// <returns></returns>
        public static async ETTask<T> LoadAssetAsync<T>(string assetPath, AssetsType assetType, bool create = false) where T : UnityEngine.Object
        {
           
            string path = GetPath(assetPath, assetType);

            ETTask<T> tcs = ETTask<T>.Create();
            AssetRequest assetRequest = Assets.LoadAssetAsync(path, typeof(T));

            //如果已经加载完成则直接返回结果（适用于编辑器模式下的异步写法和重复加载）
            if (assetRequest.isDone)
            {
                tcs.SetResult((T)assetRequest.asset);
                return await tcs;
            }

            //+=委托链，否则会导致前面完成委托被覆盖
            assetRequest.completed += (arq) => { tcs.SetResult((T)arq.asset); };
            return await tcs;
        }

        private static Type GetType(AssetsType assetType)
        {
            Type type = default;
            switch (assetType)
            {
                case AssetsType.UI:
                case AssetsType.Prefab:
                    type = typeof(GameObject);
                    break;
                case AssetsType.FUI:
                case AssetsType.Config:
                case AssetsType.TextAsset:
                    type = typeof(TextAsset);
                    break;
                case AssetsType.Texture:
                    type = typeof(Texture2D);
                    break;
                case AssetsType.Sprite:
                    type = typeof(Sprite);
                    break;            }
            return type;
        }

        private static string GetPath(string assetPath, AssetsType type)
        {
            string resultPath = default;
            switch (type)
            {
                case AssetsType.UI:
                    resultPath = "Assets/Bundles/UI/" + assetPath + ".prefab";
                    break;
                case AssetsType.Prefab:
                    resultPath = "Assets/Bundles/Prefabs/" + assetPath;
                    break;
                case AssetsType.TextAsset:
                    resultPath = "Assets/Bundles/TextAsset/" + assetPath;
                    break;
                case AssetsType.Texture:
                case AssetsType.Sprite:
                    resultPath = "Assets/Bundles/Textures/" + assetPath;
                    break;
                case AssetsType.Config:
                    resultPath = assetPath;
                    break;
                case AssetsType.FUI:
                    resultPath = "Assets/Bundles/FUI/" + assetPath + ".bytes";
                    break;
                case AssetsType.FUISprite:
                    resultPath = "Assets/Bundles/FUI/" + assetPath;
                    break;
            }
            return resultPath;
        }


        public static async ETTask<SceneAssetRequest> LoadSceneAsync(string path)
        {
            string scenePath = "Assets/_Scenes/HotScene/";
            ETTask<SceneAssetRequest> tcs = ETTask<SceneAssetRequest>.Create(false);
            SceneAssetRequest sceneAssetRequest = Assets.LoadSceneAsync(scenePath + path + ".unity", false);
            sceneAssetRequest.completed = (arq) => { tcs.SetResult(arq as SceneAssetRequest); };
            return await tcs;
        }
    }
}
